package com.example.remotecontrol.util

import android.Manifest
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import android.util.Log
import androidx.core.content.ContextCompat
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.withContext
import java.io.IOException
import java.util.UUID
import javax.inject.Inject
import javax.inject.Singleton

/**
 * 蓝牙管理器
 * 负责蓝牙设备的扫描、连接和通信
 */
@Singleton
class BluetoothManager @Inject constructor(
    private val context: Context
) {
    private val TAG = "BluetoothManager"
    
    // 蓝牙适配器
    private val bluetoothAdapter: BluetoothAdapter? by lazy {
        try {
            BluetoothAdapter.getDefaultAdapter()
        } catch (e: Exception) {
            Log.e(TAG, "Failed to get bluetooth adapter: ${e.message}")
            null
        }
    }
    
    // 当前连接的设备
    private var currentSocket: BluetoothSocket? = null
    
    // 蓝牙扫描状态
    private val _scanState = MutableStateFlow<ScanState>(ScanState.Idle)
    val scanState: StateFlow<ScanState> = _scanState.asStateFlow()
    
    // 已发现的设备列表
    private val _discoveredDevices = MutableStateFlow<List<BluetoothDevice>>(emptyList())
    val discoveredDevices: StateFlow<List<BluetoothDevice>> = _discoveredDevices.asStateFlow()
    
    // 连接状态
    private val _connectionState = MutableStateFlow<ConnectionState>(ConnectionState.Disconnected)
    val connectionState: StateFlow<ConnectionState> = _connectionState.asStateFlow()
    
    /**
     * 检查设备是否支持蓝牙
     */
    fun isBluetoothSupported(): Boolean {
        return bluetoothAdapter != null
    }
    
    /**
     * 检查蓝牙是否已启用
     */
    fun isBluetoothEnabled(): Boolean {
        return bluetoothAdapter?.isEnabled == true
    }
    
    /**
     * 检查是否有蓝牙权限
     */
    fun hasBluetoothPermissions(): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) == 
                PackageManager.PERMISSION_GRANTED &&
            ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_SCAN) == 
                PackageManager.PERMISSION_GRANTED
        } else {
            ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH) == 
                PackageManager.PERMISSION_GRANTED &&
            ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_ADMIN) == 
                PackageManager.PERMISSION_GRANTED
        }
    }
    
    /**
     * 获取配对设备列表
     */
    fun getPairedDevices(): List<BluetoothDevice> {
        if (!hasBluetoothPermissions() || !isBluetoothEnabled()) {
            return emptyList()
        }
        
        return try {
            bluetoothAdapter?.bondedDevices?.toList() ?: emptyList()
        } catch (e: Exception) {
            Log.e(TAG, "Failed to get paired devices: ${e.message}")
            emptyList()
        }
    }
    
    /**
     * 连接到指定的蓝牙设备
     */
    suspend fun connectToDevice(device: BluetoothDevice, uuid: UUID): Boolean {
        if (!hasBluetoothPermissions() || !isBluetoothEnabled()) {
            _connectionState.value = ConnectionState.Error("Missing permissions or Bluetooth disabled")
            return false
        }
        
        _connectionState.value = ConnectionState.Connecting(device.name ?: device.address)
        
        return withContext(Dispatchers.IO) {
            try {
                // 关闭之前的连接
                disconnectFromDevice()
                
                // 创建新连接
                currentSocket = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                    device.createRfcommSocketToServiceRecord(uuid)
                } else {
                    @Suppress("DEPRECATION")
                    device.createRfcommSocketToServiceRecord(uuid)
                }
                
                currentSocket?.let { socket ->
                    socket.connect()
                    _connectionState.value = ConnectionState.Connected(
                        deviceName = device.name ?: device.address,
                        deviceAddress = device.address
                    )
                    true
                } ?: run {
                    _connectionState.value = ConnectionState.Error("Failed to create socket")
                    false
                }
            } catch (e: IOException) {
                Log.e(TAG, "Failed to connect: ${e.message}")
                _connectionState.value = ConnectionState.Error("Connection failed: ${e.message}")
                currentSocket = null
                false
            }
        }
    }
    
    /**
     * 连接到指定MAC地址的蓝牙设备
     * @param address 设备MAC地址
     * @return 是否连接成功
     */
    suspend fun connect(address: String): Boolean {
        if (!hasBluetoothPermissions() || !isBluetoothEnabled()) {
            return false
        }
        
        // 查找指定地址的设备
        val device = try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                bluetoothAdapter?.getRemoteDevice(address)
            } else {
                @Suppress("DEPRECATION")
                bluetoothAdapter?.getRemoteDevice(address)
            }
        } catch (e: Exception) {
            Log.e(TAG, "Device not found: $address", e)
            null
        }
        
        return device?.let {
            connectToDevice(it, SERIAL_UUID)
        } ?: false
    }
    
    /**
     * 断开当前设备连接
     */
    suspend fun disconnectFromDevice() {
        withContext(Dispatchers.IO) {
            try {
                currentSocket?.close()
                currentSocket = null
                _connectionState.value = ConnectionState.Disconnected
            } catch (e: IOException) {
                Log.e(TAG, "Failed to disconnect: ${e.message}")
            }
        }
    }
    
    /**
     * 断开连接（BluetoothController使用）
     */
    fun disconnect() {
        kotlinx.coroutines.runBlocking {
            disconnectFromDevice()
        }
    }
    
    /**
     * 发送数据到已连接的设备
     */
    suspend fun sendCommand(command: ByteArray): Boolean {
        if (currentSocket == null || _connectionState.value !is ConnectionState.Connected) {
            return false
        }
        
        return withContext(Dispatchers.IO) {
            try {
                currentSocket?.outputStream?.write(command)
                true
            } catch (e: IOException) {
                Log.e(TAG, "Failed to send command: ${e.message}")
                false
            }
        }
    }
    
    /**
     * 发送字符串命令到已连接的设备
     * @param command 命令字符串
     * @return 是否发送成功
     */
    suspend fun sendCommand(command: String): Boolean {
        return sendCommand(command.toByteArray())
    }
    
    /**
     * 开始设备扫描
     */
    fun startScan() {
        if (!hasBluetoothPermissions() || !isBluetoothEnabled()) {
            _scanState.value = ScanState.Error("Missing permissions or Bluetooth disabled")
            return
        }
        
        _scanState.value = ScanState.Scanning
        
        // 在实际应用中，这里应该使用BroadcastReceiver监听ACTION_FOUND广播
        // 由于完整实现较为复杂，这里仅提供框架
        // 注意：Android 12+需要使用BluetoothLeScanner进行BLE扫描
        
        // 简化实现：直接使用已配对设备
        val pairedDevices = getPairedDevices()
        _discoveredDevices.value = pairedDevices
        _scanState.value = ScanState.Completed(pairedDevices.size)
    }
    
    /**
     * 停止设备扫描
     */
    fun stopScan() {
        if (_scanState.value is ScanState.Scanning) {
            _scanState.value = ScanState.Idle
            // 在实际应用中，这里应该取消BroadcastReceiver注册
        }
    }
    
    /**
     * 蓝牙扫描状态
     */
    sealed class ScanState {
        object Idle : ScanState()
        object Scanning : ScanState()
        data class Completed(val deviceCount: Int) : ScanState()
        data class Error(val message: String) : ScanState()
    }
    
    /**
     * 蓝牙连接状态
     */
    sealed class ConnectionState {
        object Disconnected : ConnectionState()
        data class Connecting(val deviceName: String) : ConnectionState()
        data class Connected(val deviceName: String, val deviceAddress: String) : ConnectionState()
        data class Error(val message: String) : ConnectionState()
    }
    
    // 预定义的UUID，用于串行通信协议
    companion object {
        val SERIAL_UUID: UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")
    }
} 